#ifndef _LIST_H_
#define _LIST_H_

struct list {
    struct list *next, *prev;
};

#define container_of(ptr, type, member) \
    ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

static inline void list_init(struct list *l)
{
    l->next = l;
    l->prev = l;
}

static inline void list_add(struct list *l, struct list *n)
{
    l->next->prev = n;
    n->next = l->next;
    l->next = n;
    n->prev = l;
}

static inline void list_add_tail(struct list *l, struct list *n)
{
    l->prev->next = n;
    n->prev = l->prev;
    l->prev = n;
    n->next = l;
}

static inline void list_del(struct list *n)
{
    n->next->prev = n->prev;
    n->prev->next = n->next;
    n->next = n;
    n->prev = n;
}

static inline int list_is_empty(struct list *l)
{
    return l->next == l;
}

static inline unsigned int list_size(struct list *l)
{
    unsigned int size = 0;
    const struct list *p = l;
    while (p->next != l) {
        p = p->next;
        size ++;
    }
    return size;
}

/**
 * get the struct for this entry
 * @ptr:    a list node
 */
#define list_entry(ptr, type, member) \
    container_of(ptr, type, member)

/**
 * list_first_entry - get the first element from a list
 * @ptr:    the list head
 */
#define list_first_entry(ptr, type, member) \
    list_entry((ptr)->next, type, member)

#define list_last_entry(ptr, type, member) \
    list_entry((ptr)->prev, type, member)

#define list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

#if 0
#define list_for_each_entry(pos, head, member) \
    for (pos = rt_list_entry((head)->next, typeof(*pos), member); \
            &pos->member != (head); \
            pos = rt_list_entry(pos->member.next, typeof(*pos), member))
#endif

#endif
